<template>
  <div class="components-chart-box">
    <h4 v-if="props.title" class="chart-title" ref="titleRef">{{ props.title }}</h4>
    <div :class="[chartClass, 'chart-container', props.bordered && 'bordered']" v-loading="loading" ref="chartRef"
      :style="{ height, width }">
    </div>
  </div>
</template>
<script lang="ts" setup>
import { onMounted, PropType, Ref, ref, watch, onUnmounted } from 'vue'
import { useECharts } from '@/hooks/web/useECharts'
import { EChartsOption } from 'echarts'
import { getCssVariableValue, getRandomColor, hexToRgb, lightenColor } from './common'
import { colorArr } from './data'
import './style.scss'
import { XAXisOption, YAXisOption } from 'echarts/types/dist/shared'

const props = defineProps({
  width: {
    type: String as PropType<string>,
    default: '100%',
  },
  height: {
    type: String as PropType<string>,
    default: '100%',
  },
  loading: {
    type: Boolean,
    default: false,
  },
  bordered: {
    type: Boolean,
    default: true,
  },
  title: {
    type: String as PropType<string>,
    default: '',
  },
  chartData: {
    type: Object as PropType<object>,
  },
  chartClass: {
    type: String as PropType<string>,
    default: '',
  },
  unit: {
    type: String as PropType<string>,
    default: '',
  },
  xyDataFieldsName: {
    type: Object as PropType<{
      xDataField: string
      yDataField: string
      lineYData: string
    }>,
    default: () => ({
      xDataField: 'xaxisList',
      yDataField: 'yaxisList',
      lineYData: 'codeyAxisList',
    }),
  },
  // 新增的堆积配置项
  stackOption: {
    type: Object as PropType<{
      barDataField: string // 用于堆积的柱状图数据字段
      stackKey: string // 堆积键名
    }>,
    default: () => ({
      barDataField: 'yaxisList',
      stackKey: 'stack1'
    })
  }
})

let resizeObserver: ResizeObserver | null = null

const chartRef = ref<HTMLDivElement | null>(null)
const titleRef = ref<HTMLDivElement | null>(null)
const { setOptions, echarts, resize } = useECharts(chartRef as Ref<HTMLDivElement>)
const gridLineColor = getCssVariableValue('--chart-grid-line-color')
const textColor = getCssVariableValue('--chart-text-color')

const returnTooltipDom = (data: any) => {
  let result = '<ul class="legend-list-bar">'
  console.log(data, 'data')
  let totalPrice:any = data.filter(item => item.componentSubType === 'bar').reduce((total, currentValue, index) => {
    return {
      ...currentValue,
      value: total.value + currentValue.value,
      seriesName: '大宗气体总费用'
    }
  },{value: 0})
  for (let item of data) {
    const { seriesName, value, color, componentSubType } = item
    const legendIcon =
      componentSubType === 'bar'
        ? `<span class="rect-bar" style="background: ${color}"></span>`
        : `<span class="rect-line" style="background: linear-gradient(${color.colorStops[0].color}, ${color.colorStops[1].color})"></span>`
    result += `<li>${legendIcon}<span >${seriesName}：</span>${value}</li>`
  }
  result += '</ul>'
  return result
}
// 标题高度 + 上间距 + 标题距离 + 两排图例
// grid 间距
const gridTop = 14 + 12 + 12 + 8 +10
const options: EChartsOption = {
  backgroundColor: '#fff',
  legend: {
    right: 16,
    padding: 0,
    textStyle: {
      color: textColor,
    },
  },
  grid: {
    left: '12px',
    right: '12px',
    bottom: '12px',
    top: gridTop,
    containLabel: true,
  },
  tooltip: {
    trigger: 'axis',
    appendToBody: true,
    className: 'echarts-line-tooltip',
    axisPointer: {
      type: 'shadow',
      label: {
        show: true,
        backgroundColor: '#333',
      },
    },
    formatter: function (params: any) {
      return returnTooltipDom(params)
    },
  },
  xAxis: {
    type: 'category',
    axisLine: {
      lineStyle: {
        color: gridLineColor,
      },
    },
    axisLabel: {
      color: textColor,
    },
  },
  yAxis: {
    nameTextStyle: {
      color: textColor,
      fontSize: '12px',
    },
    splitLine: {
      lineStyle: {
        color: gridLineColor,
      },
    },
    axisLine: {
      lineStyle: {
        color: gridLineColor,
      },
    },
    axisLabel: {
      color: textColor,
    },
    name: `单位：${props.unit}`,
  },
}

onMounted(() => {
  setData()
  resizeObserver = new ResizeObserver(() => {
    resize()
  })
  if (chartRef.value) {
    resizeObserver.observe(chartRef.value as HTMLDivElement)
  }
})

onUnmounted(() => {
  if (resizeObserver && chartRef.value) {
    resizeObserver.unobserve(chartRef.value as HTMLDivElement)
  }
})

const setData = () => {
  const { xDataField, yDataField, lineYData } = props.xyDataFieldsName
  const { barDataField, stackKey } = props.stackOption
  if (!props.chartData || !chartRef.value) return
  const chartTitleW = titleRef.value ? titleRef.value.offsetWidth : 0
  const legendWidth = chartRef.value?.clientWidth - chartTitleW - 36
  const xData = props.chartData[xDataField]
  const yData = props.chartData[yDataField]
  const barData = props.chartData[barDataField]
  let lineData = props.chartData[lineYData]
  if (!xData || (!yData && !barData) || !lineData) return
  const showUnit = (yData?.length || barData?.length) && props.unit

  setOptions({
    ...options,
    legend: getLegendData(barData || yData, lineData, legendWidth),
    grid: {
      ...options.grid,
      top: showUnit ? gridTop + 14 : gridTop,
    },
    xAxis: {
      ...options.xAxis,
      data: xData,
    } as XAXisOption,
    yAxis: [
      {
        ...options.yAxis,
        // name: `单位：m`,
      },
      {
        ...options.yAxis,
        // alignTicks: true,
        // name: `单位：w`,
      },
    ] as YAXisOption[],
    series: getSeriesData(barData || yData, lineData, stackKey),
  })
}

const getLegendData = (barData, lineData, legendWidth) => {
  const barLegendData = {
    ...options.legend,
    width: legendWidth,
    type: 'scroll',
    itemWidth: 10,
    itemHeight: 10,
    top: 4,
    icon: 'rect',
    data: barData.map((item) => ({
      name: item.name,
    }))
  }
  const lineLegendData = {
    ...options.legend,
    width: legendWidth,
    top: 20,
    type: 'scroll',
    icon: 'rect',
    itemWidth: 10,
    itemHeight: 2,
    data: lineData.map((item) => ({
      name: item.name,
    }))
  }
  return [barLegendData, lineLegendData]
}

const getSeriesData = (barData, lineData, stackKey) => {
  const barList = barData.map((item, index) => {
    const color = colorArr[index] || getRandomColor()
    return {
      ...item,
      type: 'bar',
      yAxisIndex: 0,
      itemStyle: {
        color,
        borderRadius: [4, 4, 0, 0] // 设置圆角
      },
      barMaxWidth: 28,
      stack: stackKey // 设置堆积
    }
  })

  const lineList = lineData.map((item, index) => {
    const color = barList[index]?.itemStyle.color || getRandomColor()
    const color1 = hexToRgb(color)
    const color2 = lightenColor(color1)
    return {
      ...item,
      type: 'line',
      yAxisIndex: 1,
      itemStyle: {
        color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
          { offset: 0, color: color1 },
          { offset: 1, color: color2 },
        ]),
      },
      width: 2,
    }
  })

  return barList.concat(lineList)
}

watch(
  () => props.chartData,
  (val) => {
    setData()
  },
  { immediate: true },
)

defineExpose({})
</script>
<style scoped lang="scss"></style>
<style lang="scss">
.echarts-line-tooltip {
  .legend-list-bar {
    li {
      display: flex;
      align-items: center;
      color: #666;
      font-size: 12px;
      line-height: 24px;

      &:not(:last-child) {
        margin-bottom: 4px;
      }

      .rect-bar {
        display: block;
        width: 12px;
        height: 12px;
        margin-right: 3px;
      }

      .rect-line {
        display: block;
        width: 12px;
        height: 2px;
        margin-right: 3px;
      }
    }
  }
}
</style>    